package org.example.aienglishapp.service.word;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.aienglishapp.entity.word.ErrorWord;
import org.example.aienglishapp.entity.word.UserProgress;
import org.example.aienglishapp.mapper.word.ErrorWordsMapper;
import org.example.aienglishapp.mapper.word.UserProgressMapper;
import org.mybatis.spring.MyBatisSystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static org.example.aienglishapp.service.speech.userrecording.UserRecordingService.objectMapper;


@Service("wordUserService")
public class UserService {

    @Autowired
    private UserProgressMapper userProgressMapper;

    @Autowired
    private ErrorWordsMapper errorWordsMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    // 获取用户学习进度和错词本
    public Map<String, Object> getUserProgress(Long userId, String wordBook) {
        Map<String, Object> result = new HashMap<>();
        // 获取用户指定单词书的学习进度
        List<UserProgress> progressList = userProgressMapper.getUserProgress(userId, wordBook);
        // 获取用户的错词本
        List<ErrorWord> errorWords = errorWordsMapper.getErrorWords(userId);
        result.put("progress", progressList);
        result.put("errorWords", errorWords);
        return result;
    }

    // 更新用户学习进度
    @Transactional
    public void saveUserProgress(Long userId, String wordBook, String word, Double progress, Integer timesReviewed, Timestamp lastReviewed, Integer interval) {
        logger.debug("Saving user progress for userId: {}, wordBook: {}, word: {}, progress: {}, timesReviewed: {}, lastReviewed: {}, interval: {}",
                userId, wordBook, word, progress, timesReviewed, lastReviewed, interval);

        try {
            // 查询当前用户在特定单词书和单词的进度记录
            UserProgress progressRecord = userProgressMapper.selectByUserIdAndWordBookAndWord(userId, wordBook, word);
            if (progressRecord == null) {
                logger.debug("No existing progress record found. Inserting new record.");
                progressRecord = new UserProgress(userId, wordBook, word, progress, timesReviewed, lastReviewed, interval);
                userProgressMapper.insert(progressRecord);
            } else {
                logger.debug("Found existing progress record. Updating progress.");
                progressRecord.setProgress(progress);
                progressRecord.setTimesReviewed(timesReviewed);  // 设置 timesReviewed
                progressRecord.setLastReviewed(lastReviewed);    // 设置 lastReviewed
                progressRecord.setInterval(interval);            // 设置 interval
                userProgressMapper.update(progressRecord);
            }
        } catch (MyBatisSystemException e) {
            logger.error("MyBatis exception occurred while saving progress for userId: {}, wordBook: {}, word: {}, progress: {}, timesReviewed: {}, lastReviewed: {}, interval: {}",
                    userId, wordBook, word, progress, timesReviewed, lastReviewed, interval, e);
            throw e;
        } catch (Exception e) {
            logger.error("Unexpected exception occurred while saving progress for userId: {}, wordBook: {}, word: {}, progress: {}, timesReviewed: {}, lastReviewed: {}, interval: {}",
                    userId, wordBook, word, progress, timesReviewed, lastReviewed, interval, e);
            throw e;
        }
    }


    private static final long CACHE_EXPIRATION_TIME = 3600;

    // 管理错词本


    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    //添加错误单词
    public void addErrorWord(ErrorWord errorWord) {
        try {
            // 先将错误单词添加到数据库
            errorWordsMapper.addErrorWord(errorWord);

            // 错误单词缓存的键（userId 作为前缀）
            String cacheKey = "errorWords:" + errorWord.getUserId();

            // 将 ErrorWord 对象转为 JSON 字符串
            String errorWordJson = objectMapper.writeValueAsString(errorWord);

            // 将错误单词添加到 Redis 的 Hash 中
            redisTemplate.opsForHash().put(cacheKey, errorWord.getWord(), errorWordJson); // 错误单词的 Word 作为 key，ErrorWord 对象的 JSON 字符串作为 value

            // 设置缓存的过期时间
            redisTemplate.expire(cacheKey, CACHE_EXPIRATION_TIME, TimeUnit.SECONDS);  // 设置过期时间为 1小时

            logger.info("Error word added for user: {} and word: {}", errorWord.getUserId(), errorWord.getWord());
        } catch (Exception e) {
            logger.error("Error occurred while adding error word to Redis: ", e);
            e.printStackTrace();
        }
    }

    // 删除错误单词
    @Transactional
    public void deleteErrorWord(Long userId, String word) {
        try {
            // 删除数据库中的错误单词
            int rowsDeleted = errorWordsMapper.deleteErrorWord(userId, word);
            if (rowsDeleted == 0) {
                logger.info("No records deleted for user: {} and word: {}", userId, word);
            } else {
                logger.info("Deleted rows: {}", rowsDeleted);
            }

            // 删除错误单词的缓存中对应的单词
            String cacheKey = "errorWords:" + userId;

            // 从 Redis 中删除指定的错误单词
            redisTemplate.opsForHash().delete(cacheKey, word);  // 从 Redis Hash 中删除指定单词

            // 设置缓存的过期时间
            redisTemplate.expire(cacheKey, CACHE_EXPIRATION_TIME, TimeUnit.SECONDS);  // 设置过期时间为 1小时

            logger.info("Error word deleted for user: {} and word: {}", userId, word);
        } catch (Exception e) {
            logger.error("Error occurred while deleting error word from Redis: ", e);
            e.printStackTrace();
        }
    }

}